#ifndef __M_BENCH_H__
#define __M_BENCH_H__

#include "../logs/mylog.h"
#include <chrono> //时间计算

// 测试函数
// 参数：日志器名称，线程数，日志条数，日志长度
void bench(const std::string &name, size_t thread_num, size_t log_num, size_t log_len)
{
    // 1. 先获取日志器
    mylog::Logger::ptr logger = mylog::getLogger(name);

    if (logger.get() == nullptr)
    {
        std::cout << "不存在该日志器\n";
        return;
    }
    std::cout << "线程数:" << thread_num << "\t每条日志长度:" << log_len<<std::endl;
    std::cout << "日志数:"<<log_num <<"\t输出日志大小:" << log_num * log_len / 1024 << "KB\n";
    std::cout << "********************************************\n";

    std::vector<std::thread> threads;           // 线程组
    std::vector<double> cost_times(thread_num); // 每组花费的事件
    std::string message(log_len - 1, 'A');      // 测试输出的日志信息
    // 平均分配日志条数
    size_t avg_log = log_num / thread_num;
    for (int i = 0; i < thread_num; ++i)
    {
        threads.emplace_back([&, i]()
                             {
            auto start = std::chrono::high_resolution_clock::now();//开始时间
            for(int j=0;j<avg_log;++j)
                logger->warn("%s",message.c_str());
            auto end = std::chrono::high_resolution_clock::now();//结束时间
            //耗时
            auto cost = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
            cost_times[i]=cost.count();
            std::cout<<"线程"<<i<<"处理日志数:"<<avg_log<<std::endl;
            std::cout<<"总耗时:"<<cost.count()<<" 平均耗时:"<<avg_log/cost.count()<<std::endl;
            std::cout <<"********************************************\n"; });
    }
    // 等待线程结束
    for (int i = 0; i < thread_num; ++i)
        threads[i].join();
    // 选出最长的时间
    double max_cost = 0;
    for (int i = 0; i < thread_num; ++i)
        max_cost = max_cost < cost_times[i] ? cost_times[i] : max_cost;
    std::cout << "********************************************\n";
    std::cout << "总消耗时间: " << max_cost << std::endl;
    std::cout << "平均每秒输出: " << (size_t)(log_num / max_cost) << "条日志" << std::endl;
    std::cout << "平均每秒输出: " << (size_t)(log_len * log_num / max_cost /  1024) << "KB" << std::endl;
}

// 同步日志器测试
void syncBench()
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildFormatter("[%c][%f:%l]%m");
    builder->buildLoggerType(mylog::LoggerType::LOGGER_SYNC);
    builder->buildSink<mylog::FileSink>("./logfile/sync.log");
    builder->build();
    bench("sync_logger", 3, 1000000, 50);
}

// 异步日志器测试
void asyncBench()
{
    std::unique_ptr<mylog::LoggerBuilder> builder(new mylog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildFormatter("[%c][%f:%l]%m");
    builder->buildLoggerType(mylog::LoggerType::LOGGER_ASYNC);
    builder->buildSink<mylog::FileSink>("./logfile/async.log");
    builder->build();
    bench("async_logger", 3, 1000000, 50);
}

#endif